﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using System.Data.SqlClient;
using System.Xml;
using System.IO;
using System.Net.Sockets;
using Reborn_WorldServer;

namespace Reborn_Server.App1AppHandler
{
    public class BeltManager
    {
        private Character MyCharacter;
        private Loot[] BeltLoot = new Loot[6];

        public BeltManager(Character myCharacter) 
        {
            MyCharacter = myCharacter;

            //LOAD ITEM IDs
            SqlConnection MyCon = new SqlConnection(Managers.DBConnectionString);
            SqlCommand SQLCom = new SqlCommand("Characters_Belts_Select", MyCon);
            SQLCom.CommandType = System.Data.CommandType.StoredProcedure;
            SQLCom.Parameters.AddWithValue("@CharacterID", MyCharacter.ID);

            MyCon.Open();
            SqlDataReader SDR = SQLCom.ExecuteReader();

            while (SDR.Read())
            {
                //WALK THROUGH COLUMNS
                for (int x = 0; x < 6; x++)
                {
                    if (SDR["Item" + x.ToString()] != DBNull.Value)
                    {
                        BeltLoot[x] = MyCharacter.GameHandler.CreateItem(int.Parse(SDR["Item" + x.ToString()].ToString()), int.Parse(SDR["Item" + x.ToString() + "_BoundTo"].ToString()));
                    }
                }
            }
            SDR.Close();
            SDR.Dispose();
            
            MyCon.Close();
            MyCon.Dispose();

            //Send belt to character
            UpdateBelt();
        }

        //Counts the number of occurances of the item with matching itemID, binding must be bound to me or un-bound (-1)
        public int countItems(int itemId)
        {
            int result = 0;

            lock (BeltLoot)
            {
                for (int x = 0; x < 6; x++)
                {
                    if (BeltLoot[x] != null &&
                        BeltLoot[x].ID == itemId &&
                        (BeltLoot[x].BoundTo == -1 || BeltLoot[x].BoundTo == MyCharacter.ID))
                    {
                        result++;
                    }
                }
            }

            return result;
        }
        public bool hasItem(int itemId)
        {
            lock (BeltLoot)
            {
                for (int x = 0; x < 6; x++)
                {
                    if (BeltLoot[x] != null && BeltLoot[x].ID == itemId)
                        return true;
                }
            }

            return false;
        }

        public decimal totalWeight()
        {
            decimal result = 0;

            lock (BeltLoot)
            {
                for (int x = 0; x < 6; x++)
                {
                    if (BeltLoot[x] != null)
                        result = result + BeltLoot[x].Weight;
                }
            }

            return result;
        }

        public Loot[] getBeltLootCopy()
        {
            Loot[] beltLootCpy = new Loot[6];
            lock (BeltLoot)
            {
                for (int x = 0; x < BeltLoot.Length; x++)
                    beltLootCpy[x] = BeltLoot[x];
            }
            return beltLootCpy;
        }

        public Loot RemoveBeltItem(long itemGUID)
        {
            lock (BeltLoot)
            {
                for (int x = 0; x < BeltLoot.Length; x++)
                {
                    if (BeltLoot[x] != null && BeltLoot[x].GameUID == itemGUID)
                    {
                        Loot itemToRemove = BeltLoot[x];
                        BeltLoot[x] = null;
                        return itemToRemove;
                    }
                }
            }
            return null;
        }
        public Loot GetBeltItem(long itemGUID)
        {
            lock (BeltLoot)
            {
                foreach (Loot loot in BeltLoot)
                {
                    if (loot != null && loot.GameUID == itemGUID)
                        return loot;
                }
            }
            return null;
        }
        public Loot GetBeltItem(int Position)
        {
            lock (BeltLoot)
            {
                return BeltLoot[Position];
            }
        }

        public void MoveItem(long itemGUID, int newPosition)
        {
            lock (BeltLoot)
            {
                if (BeltLoot[newPosition] != null)
                    return;

                Loot MyItem = RemoveBeltItem(itemGUID);
                if (MyItem == null)
                    return;

                BeltLoot[newPosition] = MyItem;
            }
        }

        public bool AddItem(Loot Item)
        {
            lock (BeltLoot)
            {
                for (int x = 0; x < BeltLoot.Length; x++)
                {
                    if (BeltLoot[x] == null)
                    {
                        BeltLoot[x] = Item;
                        return true;
                    }
                }
            }
            return false;
        }
        public bool AddItem(Loot Item, int Position)
        {
            lock (BeltLoot)
            {
                if (BeltLoot[Position] == null)
                {
                    BeltLoot[Position] = Item;
                    return true;
                }
            }
            return false;
        }

        public int SlotsAvailable()
        {
            int result = 0;

            lock (BeltLoot)
            {
                for (int x = 0; x < BeltLoot.Length; x++)
                {
                    if (BeltLoot[x] == null)
                        result++;
                }
            }
            return result;
        }

        //Send belt to client
        public void UpdateBelt()
        {
            try
            {
                string result = "";

                StringWriter stringWriter = new StringWriter();
                XmlTextWriter xmldoc = new XmlTextWriter(stringWriter);

                xmldoc.WriteStartElement("belt");
                string innerXml = "";

                lock (BeltLoot)
                {
                    foreach (Loot loot in BeltLoot)
                    {
                        if (loot != null)
                            innerXml = innerXml + loot.toXML(MyCharacter);
                        else
                            innerXml = innerXml + "<i/>";
                    }
                }
                xmldoc.WriteRaw(innerXml);

                xmldoc.WriteEndElement();
                xmldoc.Flush();

                xmldoc.Close();

                stringWriter.Flush();

                result = stringWriter.ToString();

                MyCharacter.ClientSocket.socket.BeginSend(result);
            }
            catch { }
        }

        public void SaveBelt()
        {
            SqlConnection MyCon = new SqlConnection(Managers.DBConnectionString);
            SqlCommand SQLCom = new SqlCommand("Characters_Belts_Update", MyCon);
            SQLCom.CommandType = System.Data.CommandType.StoredProcedure;
            SQLCom.Parameters.AddWithValue("@CharacterID", MyCharacter.ID);

            lock (BeltLoot)
            {
                for (int x = 0; x < BeltLoot.Length; x++)
                {
                    if (BeltLoot[x] != null && BeltLoot[x].ID != -1)
                    {
                        SQLCom.Parameters.AddWithValue("@Item" + x.ToString(), BeltLoot[x].ID);
                        SQLCom.Parameters.AddWithValue("@Item" + x.ToString() + "_BoundTo", BeltLoot[x].BoundTo);
                    }
                }
            }

            MyCon.Open();
            SQLCom.ExecuteNonQuery();
            MyCon.Close();
            MyCon.Dispose();
        }
    }
}
